package cn.xeblog.plugin.game.dld;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.xeblog.commons.entity.User;
import cn.xeblog.commons.enums.Game;
import cn.xeblog.plugin.action.handler.command.OverCommandHandler;
import cn.xeblog.plugin.annotation.DoGame;
import cn.xeblog.plugin.cache.DataCache;
import cn.xeblog.plugin.game.AbstractGame;
import cn.xeblog.plugin.game.dld.model.Result;
import cn.xeblog.plugin.game.dld.model.common.Page;
import cn.xeblog.plugin.game.dld.model.dto.*;
import cn.xeblog.plugin.game.dld.model.entity.InstanceNpc;
import cn.xeblog.plugin.game.dld.model.vo.*;
import cn.xeblog.plugin.game.dld.ui.IKunUi;
import cn.xeblog.plugin.game.dld.ui.game.InstanceListTab;
import cn.xeblog.plugin.game.dld.ui.game.MasterGame;
import cn.xeblog.plugin.game.dld.ui.game.PlayerInfoTab;
import cn.xeblog.plugin.game.dld.ui.game.PvpTab;
import cn.xeblog.plugin.game.dld.ui.game.playerPackege.EntryItemTab;
import cn.xeblog.plugin.game.dld.ui.game.playerPackege.PackageTab;
import cn.xeblog.plugin.game.dld.ui.login.AccountLogin;
import cn.xeblog.plugin.game.dld.ui.login.LoginFormUi;
import cn.xeblog.plugin.game.dld.ui.login.MacLogin;
import cn.xeblog.plugin.game.dld.utils.HttpSendUtil;
import cn.xeblog.plugin.game.dld.utils.ResultUtil;
import cn.xeblog.plugin.util.AlertMessagesUtil;
import cn.xeblog.plugin.util.NotifyUtils;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.panels.VerticalBox;
import com.jgoodies.forms.layout.CellConstraints;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.*;

import static cn.xeblog.plugin.game.dld.Const.*;


/**
 * @author eleven
 * @date 2023/10/24 12:27
 * @apiNote
 */
@DoGame(Game.IKUN)
@Slf4j
public class IKunDldXl extends AbstractGame {

    /**
     * 主面板
     */
    private JPanel mainPanel;

    private JPanel centerPanel;

    private JPanel footerPanel;

    private JButton loginBtn;

    private Integer loginType = 0;
    /**
     * 切换用的tab页
     */
    private JTabbedPane tab;

    private VerticalBox box;

    private JTextArea fightArea;

    private JPanel playerArea;

    private final FlowLayout FLOW_LEFT_LAYOUT = new FlowLayout(FlowLayout.LEFT);

    //=====以下为各种UI=====
    private IKunUi iKunUi;

    private LoginFormUi loginFormUi;

    private MacLogin macLogin;

    private AccountLogin accountLogin;

    private MasterGame masterGame;

    private PvpTab pvpTab;

    private PlayerInfoTab playerInfoTab;

    private InstanceListTab instanceListTab;

    private PackageTab packageTab;

    /**
     * 详细的背包分类tab
     */
    private JTabbedPane packageTypeTab;

    /**
     * 详情tab
     */
    private EntryItemTab playerWeaponTab;
    private EntryItemTab playerSkillTab;
    private EntryItemTab playerPropTab;
    private EntryItemTab playerMaterialsTab;

    /**
     * 当前玩家
     */
    private PlayerInfoVo currentPlayer;

    private final Dimension maximumSize = new Dimension(800, 800);
    private final Dimension minimumSize = new Dimension(800, 650);

    private Page page;
    // 分页参数
    private JLabel pageLabel;

    private JTextField searchTextField;

    private JTextArea detailArea;

    private PlayerWeaponVo chooseWeapon;
    private PlayerSKillVo chooseSkill;
    private PackagePropsVo chooseProps;


    final Map<PlayerWeaponVo, JPanel> weaponMap = new HashMap<>(1);
    final Map<PlayerSKillVo, JPanel> sKillMap = new HashMap<>(1);
    final Map<PackagePropsVo, JPanel> propsMap = new HashMap<>(1);

    private Gson gson = new GsonBuilder().setPrettyPrinting().create();

    @Override
    protected void start() {
        log.info("开始了");
        initLoginForm();
        centerPanel.removeAll();
        box = new VerticalBox();
        box.setMaximumSize(maximumSize);
        box.add(loginFormUi.getLoginPanel());
        centerPanel.setPreferredSize(maximumSize);
        centerPanel.add(box);
        centerPanel.updateUI();
        log.info("结束了");
    }

    /**
     * 初始化游戏面板
     * 玩家输入 #play 9之后加载此方法
     */
    @Override
    protected void init() {
        log.info("当前初始化游戏面板");
        iKunUi = new IKunUi(GAME_NAME);
        if (mainPanel == null) {
            mainPanel = iKunUi.getMainPanel();
            centerPanel = iKunUi.getCenterPanel();
            footerPanel = iKunUi.getFooterPanel();
        }
        mainPanel.setPreferredSize(maximumSize);
        footerPanel.add(getStartGameButton());
        footerPanel.add(getExitButton());
        mainPanel.updateUI();
        log.info("初始化完成");
    }

    /**
     * 获取游戏的主窗口
     *
     * @return JPanel  游戏主UI
     */
    @Override
    protected JPanel getComponent() {
        if (iKunUi == null) {
            iKunUi = new IKunUi(GAME_NAME);
        }
        return mainPanel;
    }

    /**
     * 获取开始游戏按钮
     *
     * @return JButton 开始游戏
     */
    private JButton getStartGameButton() {
        JButton button = new JButton("开始游戏");
        button.addActionListener(e -> start());
        return button;
    }

    /**
     * 获取返回游戏的按钮加载到页面最下方的footerBtn中
     *
     * @return JButton  返回游戏按钮
     */
    private JButton getBackGameButton() {
        JButton button = new JButton("返回游戏");
        button.addActionListener(e -> init());
        return button;
    }

    /**
     * 初始化登录
     */
    private void initLoginForm() {
        loginFormUi = new LoginFormUi();
        JComboBox<String> typeComboBox = loginFormUi.getTypeComboBox();
        JPanel typePanel = loginFormUi.getTypePanel();
        typeComboBox.addItem("MAC自动登录");
        typeComboBox.addItem("账号密码登录");
        initMacLogin();
        typePanel.add(macLogin.getMacPanel());
        typeComboBox.addActionListener(e -> {
            loginType = typeComboBox.getSelectedIndex();
            log.info("当前选择登录类型 - {}", loginType);
            typePanel.removeAll();
            switch (loginType) {
                case 0:
                    typePanel.add(macLogin.getMacPanel());
                    break;
                case 1:
                    initAccountLogin();
                    typePanel.add(accountLogin.getAccountLoginPanel());
                default:
                    NotifyUtils.info(GAME_NAME, "登录类型未实现");
                    break;
            }
            typePanel.updateUI();
            log.info("登录类型UI刷新成功");
        });
        loadLoginAction();
    }

    /**
     * 使用Mac地址快读登录
     */
    private void initMacLogin() {
        macLogin = new MacLogin();
        loginBtn = macLogin.getLoginBtn();
        loadLoginAction();
    }

    /**
     * 初始化账号登录
     * 点击Mac登录之后默认添加一个账号，
     * 密码最初和账号一致
     */
    private void initAccountLogin() {
        accountLogin = new AccountLogin();
        loginBtn = accountLogin.getLoginBtn();
        loadLoginAction();
    }

    /**
     * 加载登录action
     * 支持三种登录方式
     *
     * @apiNote 1. mac地址自动登录<br/>
     * 根据用户在xechat登录的mac地址自动注册，<br/>
     * 没有账号会默认创建一个账号，初始密码为账号<br/>
     * 2. 账号密码登录<br/>
     * 3. 邮箱登录 未实现<br/>
     */
    private void loadLoginAction() {
        log.info("加载登录按钮事件");
        loginBtn.addActionListener(e -> {
            switch (loginType) {
                case 0:
                    loginByMac();
                    break;
                case 1:
                    loginByAccount();
                    break;
                default:
                    AlertMessagesUtil.showInfoDialog(GAME_NAME, "请选择MAC登录");
                    break;
            }
        });
    }

    /**
     * 初始化主游戏Tab面板
     */
    private void initMasterGame() {
        log.info("加载登录按钮事件完成");
        log.info("开始加载游戏主面板");
        masterGame = new MasterGame();
        tab = masterGame.getTab();
        tab.setMinimumSize(minimumSize);
        loadPvpTab();
        JPanel gamePanel = masterGame.getGamePanel();

        tab.setPreferredSize(maximumSize);
        log.info("GameTabbed width {} ， height {}", tab.getWidth(), tab.getHeight());
        refreshCenterPanel(gamePanel);
        log.info("游戏面板加载完成");
        tab.addChangeListener(e -> {
            int selectedIndex = tab.getSelectedIndex();
            switch (selectedIndex) {
                case 0:
                    loadPvpTab();
                    break;
                case 1:
                    loadInstanceTab();
                    break;
                case 2:
                    loadPlayerInfoTab();
                    break;
                case 3:
                    loadPackageTab();
                    break;
                case 4:
                    loadBossTab();
                    break;
                default:
                    break;
            }
        });
    }

    /**
     * pvp Tab页
     */
    private void loadPvpTab() {
        tab.setSelectedIndex(0);
        JPanel pvpPanel = masterGame.getPvpPanel();
        pvpPanel.removeAll();
        pvpPanel.setLayout(FLOW_LEFT_LAYOUT);
        pvpTab = new PvpTab();
        playerArea = pvpTab.getPlayerArea();
        fightArea = pvpTab.getFightArea();
        pageLabel = pvpTab.getPageLabel();
        JButton clearBtn = pvpTab.getClearBtn();
        clearBtn.addActionListener(e -> {
            fightArea.setText(Const.CLEAR_MSG);
            updateUI(tab, box, centerPanel);
        });
        JButton refreshBtn = pvpTab.getRefreshBtn();
        invoke(this::refreshPlayerList);
        refreshBtn.addActionListener(e -> invoke(this::refreshPlayerList));
        // 上一页下一页操作
        JButton prevBtn = pvpTab.getPrevBtn();
        prevBtn.addActionListener(e -> {
            if (page == null) {
                NotifyUtils.info(GAME_NAME, "分页数据尚未初始化");
                invoke(this::refreshPlayerList);
                return;
            }
            if (page.getCurrent() <= 1) {
                NotifyUtils.info(GAME_NAME, "当前已经是首页了");
                return;
            }
            page.setCurrent(page.getCurrent() - 1);
            invoke(this::refreshPlayerList);
        });
        JButton nextBtn = pvpTab.getNextBtn();

        nextBtn.addActionListener(e -> {
            if (page == null) {
                NotifyUtils.info(GAME_NAME, "分页数据尚未初始化");
                invoke(this::refreshPlayerList);
                return;
            }
            if (page.getCurrent() >= page.getPages()) {
                NotifyUtils.info(GAME_NAME, "当前已经是末页了");
                return;
            }
            page.setCurrent(page.getCurrent() + 1);
            log.info("当前page {}", page);
            invoke(this::refreshPlayerList);
        });
        // 跳转按钮
        JButton toBtn = pvpTab.getToBtn();
        toBtn.setToolTipText("左侧输入框输入页数进行跳转");
        toBtn.addActionListener(e -> {
            String text = searchTextField.getText();
            if (StrUtil.isBlank(text)) {
                NotifyUtils.info(GAME_NAME, "请输入页数");
                return;
            }
            if (!NumberUtil.isNumber(text)) {
                NotifyUtils.info(GAME_NAME, "必须输入数字");
                return;
            }
            searchTextField.setText(null);
            page.setCurrent(Long.parseLong(text));
            this.refreshPlayerList();
        });
        JButton searchBtn = pvpTab.getSearchBtn();
        searchTextField = pvpTab.getSearchTextField();
        searchBtn.addActionListener(e -> invoke(this::refreshPlayerList));
        pvpPanel.add(pvpTab.getPvpPanel());
        updateUI(tab, pvpPanel);
    }

    /**
     * 副本tab
     */
    private void loadInstanceTab() {
        tab.setSelectedIndex(1);
        JPanel instancePanel = masterGame.getInstancePanel();
        instancePanel.removeAll();
        instancePanel.setLayout(FLOW_LEFT_LAYOUT);
        instanceListTab = new InstanceListTab();
        JPanel instanceListPanel = instanceListTab.getInstanceListPanel();
        invoke(() -> {
            Result result = HttpSendUtil.post(Const.INSTANCE_LIST, null);
            List<InstanceVo> instanceVoList = ResultUtil.convertListData(result, InstanceVo.class);
            instanceListPanel.setLayout(new GridLayout(instanceVoList.size(), 1));
            log.info("当前副本列表 {}", instanceVoList);
            JPanel itemPanel = null;
            JLabel itemLabel = null;
            JButton itemBtn = null;
            for (InstanceVo instance : instanceVoList) {
                itemPanel = new JPanel(FLOW_LEFT_LAYOUT);
                Integer accessLevel = instance.getAccessLevel();
                itemLabel = new JLabel(String.format("%d [%s] [%d级准入] [层数 %d]",
                        instanceVoList.indexOf(instance),
                        instance.getInstanceName(),
                        accessLevel,
                        instance.getFloorNum()));
                boolean accessFlag = currentPlayer.getLevel() >= accessLevel;
                itemLabel.setForeground(accessFlag ? JBColor.GREEN : JBColor.GRAY);
                itemBtn = new JButton("进入副本");
                if (!accessFlag) {
                    itemBtn.setEnabled(false);
                }
                itemBtn.addActionListener(e -> {
                    if (!accessFlag) {
                        NotifyUtils.error(GAME_NAME, "等级不足", true);
                    } else {
                        loadInstanceNpc(instance);
                    }
                });
                itemPanel.add(itemLabel);
                itemPanel.add(itemBtn);
                instanceListPanel.add(itemPanel);
            }
        });

        instancePanel.add(instanceListPanel);
        updateUI(tab, instancePanel);
    }

    /**
     * 玩家信息
     */
    private void loadPlayerInfoTab() {
        tab.setSelectedIndex(2);
        JPanel playerPanel = masterGame.getPlayerPanel();
        playerPanel.removeAll();
        playerInfoTab = new PlayerInfoTab();
        JLabel lvLabel = playerInfoTab.getLvLabel();
        JProgressBar lvProgress = playerInfoTab.getLvProgress();
        JLabel energyLabel = playerInfoTab.getEnergyLabel();
        JProgressBar energyProgress = playerInfoTab.getEnergyProgress();
        invoke(() -> {
            Result result = HttpSendUtil.post(Const.PLAYER_DETAIL, new PlayerDto());
            if (Const.ERROR_CODE.equals(result.getCode())) {
                NotifyUtils.error(GAME_NAME, result.toString(), false);
            } else {
                PlayerInfoVo playerInfoVo = ResultUtil.convertObjData(result, PlayerInfoVo.class);
                String lvTips = String.format("%d/%d", playerInfoVo.getExp(), playerInfoVo.getNextLvExp());
                lvLabel.setText(String.format("Lv:%d(%s)", playerInfoVo.getLevel(), lvTips));
                lvProgress.setMaximum(playerInfoVo.getNextLvExp());
                lvProgress.setValue(playerInfoVo.getExp());
                // 体力
                energyLabel.setText(String.format("体力: (%d/%d)", playerInfoVo.getEnergy(), playerInfoVo.getMaxEnergy()));
                energyProgress.setValue(playerInfoVo.getEnergy());
                energyProgress.setMaximum(playerInfoVo.getMaxEnergy());
                playerInfoTab.getGoldLabel().setText(StrUtil.format("金币: {}", playerInfoVo.getGoldNum()));
                // 昵称
                playerInfoTab.getNickname().setText(String.format("昵称: %s", playerInfoVo.getNickname()));
                // 账号
                playerInfoTab.getAccount().setText(String.format("账号: %s", StrUtil.isBlank(playerInfoVo.getAccount()) ? "暂无" : playerInfoVo.getAccount()));

                // hp
                playerInfoTab.getHp().setText(String.format("生命: %d", playerInfoVo.getHp()));
                // 攻击
                playerInfoTab.getAttack().setText(String.format("攻击: %d", playerInfoVo.getAttack()));

                // 防御
                playerInfoTab.getDefender().setText(String.format("防御: %d", playerInfoVo.getDefence()));
                // 命中率
                playerInfoTab.getHit().setText(String.format("命中率: %.3f", playerInfoVo.getHitRate()));

                // 闪避
                playerInfoTab.getFlee().setText(String.format("闪避率: %.3f", playerInfoVo.getFlee()));
                // 连击
                playerInfoTab.getCombo().setText(String.format("连击率: %.3f", playerInfoVo.getComboRate()));
                // 速度
                playerInfoTab.getCritical().setText(String.format("暴击率:%.3f", playerInfoVo.getCriticalChance()));
                // 速度
                playerInfoTab.getSpeed().setText(String.format("速度:%d", playerInfoVo.getSpeed()));

            }
        });
        playerPanel.setLayout(FLOW_LEFT_LAYOUT);
        playerPanel.add(playerInfoTab.getInfoPanel());
    }

    /**
     * 背包
     */
    private void loadPackageTab() {
        tab.setSelectedIndex(3);
        JPanel packagePanel = masterGame.getPackagePanel();
        packagePanel.removeAll();
        packagePanel.setLayout(FLOW_LEFT_LAYOUT);
        packagePanel.setPreferredSize(maximumSize);
        packageTab = new PackageTab();
        packageTypeTab = packageTab.getTab();
        packageTypeTab.setSelectedIndex(1);
        JPanel packageTabPanel = packageTab.getPackageTabPanel();
        packagePanel.add(packageTabPanel);
        loadPlayerWeapon();
        packageTypeTab.addChangeListener(e -> {
            int packageType = packageTypeTab.getSelectedIndex();
            log.info("当前类型{}", packageType);
            switch (packageType) {
                case 0:
                    loadPlayerSkill();
                    break;
                case 1:
                    loadPlayerWeapon();
                    break;
                case 2:
                    loadPlayerMaterials();
                    break;
                case 3:
                    loadPlayerProps();
                    break;
                default:
                    NotifyUtils.info(GAME_NAME, packageType + "功能没开发");
            }
        });
    }

    /**
     * 加载玩家道具
     */
    private void loadPlayerProps() {
        JPanel propPanel = packageTab.getPropPanel();
        propPanel.removeAll();
        playerPropTab = new EntryItemTab();
        JPanel detailPanel = playerPropTab.getDetailPanel();
        refreshPlayerProps(PROPS);
        detailArea = playerPropTab.getDetailArea();
        detailArea.setText("点击查看技能描述");
        detailArea.setColumns(COLUMN_NUM);
        propPanel.add(detailPanel, new CellConstraints());
        JButton enhancedBtn = playerPropTab.getEnhancedBtn();
        enhancedBtn.setText("使用");
        enhancedBtn.addActionListener(e -> {
            if (chooseProps == null) {
                NotifyUtils.info(GAME_NAME, "请选择要使用道具");
                return;
            }
            String inputStr = AlertMessagesUtil.showInputDialog(GAME_NAME, StrUtil.format("请输入使用道具{}的数量", chooseProps.getPropsName()));
            if (StrUtil.isBlank(inputStr)) {
                NotifyUtils.info(GAME_NAME, "用户取消丢弃");
                return;
            }
            boolean isNumber = NumberUtil.isInteger(inputStr);
            if (!isNumber) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            long number = Long.parseLong(inputStr);
            if (number < 0) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            invoke(() -> {
                PropsOperationDto dto = new PropsOperationDto(chooseProps.getId(), currentPlayer.getId(), number);
                Result result = HttpSendUtil.post(OPEN_PROPS, dto);
                NotifyUtils.info(GAME_NAME, gson.toJson(result));
                refreshPlayerProps(PROPS);
            });
        });
        // 丢弃
        playerPropTab.getDiscardBtn().addActionListener( e -> {
            if (chooseProps == null) {
                NotifyUtils.info(GAME_NAME, "请选择要丢弃的道具");
                return;
            }
            String inputStr = AlertMessagesUtil.showInputDialog(GAME_NAME, StrUtil.format("请输入丢弃道具{}的数量", chooseProps.getPropsName()));
            if (StrUtil.isBlank(inputStr)) {
                NotifyUtils.info(GAME_NAME, "用户取消丢弃");
                return;
            }
            boolean isNumber = NumberUtil.isInteger(inputStr);
            if (!isNumber) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            long number = Long.parseLong(inputStr);
            if (number < 0) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            invoke(() -> {
                PropsOperationDto dto = new PropsOperationDto(chooseProps.getId(), currentPlayer.getId(), number);
                Result result = HttpSendUtil.post(DISCARD_PROPS, dto);
                NotifyUtils.info(GAME_NAME, gson.toJson(result));
                refreshPlayerProps(PROPS);
            });
        });
        // 售卖
        playerPropTab.getSellBtn().addActionListener(e -> {
            if (chooseProps == null) {
                NotifyUtils.info(GAME_NAME, "请选择要丢弃的道具");
                return;
            }
            String inputStr = AlertMessagesUtil.showInputDialog(GAME_NAME, StrUtil.format("请输入售卖道具{}的数量", chooseProps.getPropsName()));
            if (StrUtil.isBlank(inputStr)) {
                NotifyUtils.info(GAME_NAME, "用户取消丢弃");
                return;
            }
            boolean isNumber = NumberUtil.isInteger(inputStr);
            if (!isNumber) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            long number = Long.parseLong(inputStr);
            if (number < 0) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            invoke(() -> {
                PropsOperationDto dto = new PropsOperationDto(chooseProps.getId(), currentPlayer.getId(), number);
                Result result = HttpSendUtil.post(SELL_PROPS, dto);
                NotifyUtils.info(GAME_NAME, gson.toJson(result));
                refreshPlayerProps(PROPS);
            });

        });
        JButton extBtn = playerPropTab.getExtBtn();
        extBtn.setText("清空");
        extBtn.addActionListener(e -> {
            chooseProps = null;
            propsMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
            propsMap.clear();
            detailArea.setText("");
        });
    }

    private void refreshPlayerProps(String type) {
        invoke(() -> {
            QueryPackageEntryDto dto = new QueryPackageEntryDto();
            dto.setType(type);
            dto.setPlayerId(currentPlayer.getId());
            Result result = HttpSendUtil.post(GET_ALL_PROPS, dto);
            if (Objects.equals(result.getCode(), ERROR_CODE)) {
                NotifyUtils.error(GAME_NAME, result.getMessage());
                return;
            }
            List<PackagePropsVo> propsVoList = ResultUtil.convertListData(result, PackagePropsVo.class);
            List<List<PackagePropsVo>> partition = Lists.partition(propsVoList, 4);
            EntryItemTab currentTab = PROPS.equals(type) ? playerPropTab : playerMaterialsTab;
            if (chooseProps != null) {
                propsVoList.stream()
                        .filter(item -> item.getId().equals(chooseProps.getId()))
                        .findFirst()
                        .ifPresent(item -> currentTab.getDetailArea().setText(item.toString()));
            }
            JPanel propsPanel = currentTab.getPropsPanel();
            propsPanel.removeAll();
            propsPanel.setLayout(new GridLayout(partition.size(), 4));
            JPanel detailRowPanel = null;
            JPanel detailPanel = null;
            JLabel detailLabel = null;
            for (List<PackagePropsVo> propsVos : partition) {
                detailRowPanel = new JPanel(new GridLayout(1, 4));
                for (PackagePropsVo prop : propsVos) {
                    detailPanel = new JPanel();
                    detailPanel.setBorder(new LineBorder(JBColor.YELLOW, 1));
                    detailLabel = new JLabel(prop.getPropsName());
                    // TODO: 2023/12/21 这里需要从展示文字变更为展示物品icon
                    JPanel finalDetailPanel = detailPanel;
                    detailPanel.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            JPanel choosePanel = propsMap.get(prop);
                            chooseProps = prop;
                            if (choosePanel == null) {
                                propsMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
                                propsMap.clear();
                            }
                            finalDetailPanel.setBorder(new LineBorder(JBColor.RED, 2));
                            propsMap.put(prop, finalDetailPanel);
                            currentTab.getDetailArea().setText(prop.toString());
                        }
                    });
                    detailPanel.add(detailLabel, BorderLayout.CENTER);
                    detailRowPanel.add(detailPanel);
                }
                propsPanel.add(detailRowPanel);
            }
            log.info("当前的数据 {}", partition);
        });
    }

    /**
     * 加载玩家材料
     */
    private void loadPlayerMaterials() {
        JPanel materialsPanel = packageTab.getMaterialsPanel();
        materialsPanel.removeAll();
        playerMaterialsTab = new EntryItemTab();
        JPanel detailPanel = playerMaterialsTab.getDetailPanel();
        refreshPlayerProps(MATERIALS);
        detailArea = playerMaterialsTab.getDetailArea();
        detailArea.setText("点击查看材料描述");
        detailArea.setColumns(COLUMN_NUM);
        materialsPanel.add(detailPanel, new CellConstraints());
        playerMaterialsTab.getEnhancedBtn().setVisible(false);
        // 丢弃
        playerMaterialsTab.getDiscardBtn().addActionListener( e -> {
            if (chooseProps == null) {
                NotifyUtils.info(GAME_NAME, "请选择要丢弃的道具");
                return;
            }
            String inputStr = AlertMessagesUtil.showInputDialog(GAME_NAME, StrUtil.format("请输入丢弃道具{}的数量", chooseProps.getPropsName()));
            if (StrUtil.isBlank(inputStr)) {
                NotifyUtils.info(GAME_NAME, "用户取消丢弃");
                return;
            }
            boolean isNumber = NumberUtil.isLong(inputStr);
            if (!isNumber) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            long number = Long.parseLong(inputStr);
            if (number < 0) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            invoke(() -> {
                PropsOperationDto dto = new PropsOperationDto(chooseProps.getId(), currentPlayer.getId(), number);
                Result result = HttpSendUtil.post(DISCARD_PROPS, dto);
                NotifyUtils.info(GAME_NAME, gson.toJson(result));
                refreshPlayerProps(MATERIALS);
            });
        });
        // 售卖
        playerMaterialsTab.getSellBtn().addActionListener(e -> {
            if (chooseProps == null) {
                NotifyUtils.info(GAME_NAME, "请选择要丢弃的道具");
                return;
            }
            String inputStr = AlertMessagesUtil.showInputDialog(GAME_NAME, StrUtil.format("请输入售卖道具{}的数量", chooseProps.getPropsName()));
            if (StrUtil.isBlank(inputStr)) {
                NotifyUtils.info(GAME_NAME, "用户取消丢弃");
                return;
            }
            boolean isNumber = NumberUtil.isInteger(inputStr);
            if (!isNumber) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            long number = Long.parseLong(inputStr);
            if (number < 0) {
                NotifyUtils.info(GAME_NAME, "输入非法，请输入正整数");
                return;
            }
            invoke(() -> {
                PropsOperationDto dto = new PropsOperationDto(chooseProps.getId(), currentPlayer.getId(), number);
                Result result = HttpSendUtil.post(SELL_PROPS, dto);
                NotifyUtils.info(GAME_NAME, gson.toJson(result));
                refreshPlayerProps(MATERIALS);
            });

        });
        JButton extBtn = playerMaterialsTab.getExtBtn();
        extBtn.setText("清空");
        extBtn.addActionListener(e -> {
            chooseProps = null;
            propsMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
            propsMap.clear();
            detailArea.setText("");
        });

    }


    private void loadPlayerSkill() {
        JPanel skillPanel = packageTab.getSkillPanel();
        skillPanel.removeAll();
        playerSkillTab = new EntryItemTab();
        JPanel detailPanel = playerSkillTab.getDetailPanel();
        refreshPlayerSkill();
        detailArea = playerSkillTab.getDetailArea();
        detailArea.setText("点击查看技能描述");
        detailArea.setColumns(COLUMN_NUM);
        skillPanel.add(detailPanel, new CellConstraints());
        JButton extBtn = playerSkillTab.getExtBtn();
        extBtn.setText("清空");
        extBtn.addActionListener(e -> {
            chooseSkill = null;
            sKillMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
            sKillMap.clear();
            detailArea.setText("");
        });
        JButton enhancedBtn = playerSkillTab.getEnhancedBtn();
        enhancedBtn.setText("升级");
        enhancedBtn.addActionListener(e -> {
            invoke(() -> {
                if (chooseSkill == null) {
                    NotifyUtils.info(GAME_NAME, "请选择要升级的技能");
                    return;
                }

                if (AlertMessagesUtil.showYesNoDialog(GAME_NAME, StrUtil.format("是否强化升级{}", chooseSkill.getSkillName()))) {
                    invoke(() -> {
                        Result result = HttpSendUtil.post(UPGRADE_SKILL, chooseSkill);
                        NotifyUtils.info(GAME_NAME, gson.toJson(result));
                    });
                    loadPlayerWeapon();
                } else {
                    NotifyUtils.info(GAME_NAME, "玩家取消升级");
                }
            });
        });
        playerSkillTab.getSellBtn().setVisible(false);
        playerSkillTab.getDiscardBtn().setVisible(false);
        updateUI(skillPanel);
    }

    private void refreshPlayerSkill() {
        invoke(() -> {
            log.info("当前获取玩家武器开始");
            QueryWeaponDto dto = new QueryWeaponDto();
            dto.setPlayerId(currentPlayer.getId());
            Result result = HttpSendUtil.post(Const.GET_ALL_SKILL, dto);
            List<PlayerSKillVo> sKillVoList = ResultUtil.convertListData(result, PlayerSKillVo.class);
            List<List<PlayerSKillVo>> partition = Lists.partition(sKillVoList, 4);
            JPanel propsPanel = playerSkillTab.getPropsPanel();
            propsPanel.setLayout(new GridLayout(partition.size(), 4));
            JPanel detailRowPanel = null;
            JPanel detailPanel = null;
            JLabel detailLabel = null;
            for (List<PlayerSKillVo> skills : partition) {
                detailRowPanel = new JPanel(new GridLayout(1, 4));
                for (PlayerSKillVo skill : skills) {
                    detailPanel = new JPanel();
                    detailPanel.setBorder(new LineBorder(JBColor.YELLOW, 1));
                    detailLabel = new JLabel(skill.getSkillName());
                    // TODO: 2023/12/21 这里需要从展示文字变更为展示物品icon
                    JPanel finalDetailPanel = detailPanel;
                    detailPanel.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            JPanel choosePanel = sKillMap.get(skill);
                            chooseSkill = skill;
                            if (choosePanel == null) {
                                sKillMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
                                sKillMap.clear();
                            }
                            finalDetailPanel.setBorder(new LineBorder(JBColor.RED, 2));
                            sKillMap.put(skill, finalDetailPanel);
                            playerSkillTab.getDetailArea().setText(skill.toString());
                        }
                    });
                    detailPanel.add(detailLabel, BorderLayout.CENTER);
                    detailRowPanel.add(detailPanel);
                }
                propsPanel.add(detailRowPanel);
            }
            log.info("当前的数据 {}", partition);
        });
    }

    private void loadPlayerWeapon() {
        JPanel weaponPanel = packageTab.getWeaponPanel();
        weaponPanel.removeAll();
        playerWeaponTab = new EntryItemTab();
        JPanel detailPanel = playerWeaponTab.getDetailPanel();
        refreshPlayerWeapon();
        detailArea = playerWeaponTab.getDetailArea();
        detailArea.setText("点击查看物品描述");
        detailArea.setColumns(COLUMN_NUM);
        weaponPanel.add(detailPanel, new CellConstraints());
        updateUI(weaponPanel);
        // 丢弃
        JButton discardBtn = playerWeaponTab.getDiscardBtn();
        discardBtn.addActionListener(e -> {
            if (chooseWeapon == null) {
                NotifyUtils.info(GAME_NAME, "请选择要丢弃的武器");
                return;
            }

            if (AlertMessagesUtil.showYesNoDialog(GAME_NAME, "是否确认丢弃武器" + chooseWeapon.getWeaponName())) {
                invoke(() -> {
                    Result result = HttpSendUtil.post(DISCARD_WEAPON, chooseWeapon);
                    NotifyUtils.info(GAME_NAME, gson.toJson(result));
                });
                loadPlayerWeapon();
            } else {
                NotifyUtils.info(GAME_NAME, "玩家取消丢弃");
            }
        });
        // 售卖
        JButton sellBtn = playerWeaponTab.getSellBtn();
        sellBtn.addActionListener(e -> {
            if (chooseWeapon == null) {
                NotifyUtils.info(GAME_NAME, "请选择要售卖的武器");
                return;
            }

            if (AlertMessagesUtil.showYesNoDialog(GAME_NAME, StrUtil.format("是否售卖武器{},售价{}金币", chooseWeapon.getWeaponName(), chooseWeapon.getSellingPrice()))) {
                invoke(() -> {
                    Result result = HttpSendUtil.post(SELL_WEAPON, chooseWeapon);
                    NotifyUtils.info(GAME_NAME, gson.toJson(result));
                });
                loadPlayerWeapon();
            } else {
                NotifyUtils.info(GAME_NAME, "玩家取消售卖");
            }
        });
        // 强化
        JButton enhancedBtn = playerWeaponTab.getEnhancedBtn();
        enhancedBtn.addActionListener(e -> {
            if (chooseWeapon == null) {
                NotifyUtils.info(GAME_NAME, "请选择要强化的武器");
                return;
            }

            if (AlertMessagesUtil.showYesNoDialog(GAME_NAME, StrUtil.format("是否强化武器{}", chooseWeapon.getWeaponName()))) {
                invoke(() -> {
                    Result result = HttpSendUtil.post(ENHANCED_WEAPON, chooseWeapon);
                    NotifyUtils.info(GAME_NAME, gson.toJson(result));
                });
                loadPlayerWeapon();
            } else {
                NotifyUtils.info(GAME_NAME, "玩家取消强化");
            }
        });
        JButton extBtn = playerWeaponTab.getExtBtn();
        extBtn.setText("清空");
        extBtn.addActionListener(e -> {
            chooseWeapon = null;
            weaponMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
            weaponMap.clear();
            detailArea.setText("");
        });
    }

    private void refreshPlayerWeapon() {
        invoke(() -> {
            log.info("当前获取玩家武器开始");
            QueryWeaponDto dto = new QueryWeaponDto();
            dto.setPlayerId(currentPlayer.getId());
            Result result = HttpSendUtil.post(Const.GET_ALL_WEAPON, dto);
            List<PlayerWeaponVo> weaponList = ResultUtil.convertListData(result, PlayerWeaponVo.class);
            List<List<PlayerWeaponVo>> partition = Lists.partition(weaponList, 4);
            JPanel propsPanel = playerWeaponTab.getPropsPanel();
            propsPanel.setLayout(new GridLayout(partition.size(), 4));
            JPanel detailRowPanel = null;
            JPanel detailPanel = null;
            JLabel detailLabel = null;
            for (List<PlayerWeaponVo> weapons : partition) {
                detailRowPanel = new JPanel(new GridLayout(1, 4));
                for (PlayerWeaponVo weapon : weapons) {
                    detailPanel = new JPanel();
                    detailPanel.setBorder(new LineBorder(JBColor.YELLOW, 1));
                    detailLabel = new JLabel(weapon.getWeaponName());
                    // TODO: 2023/12/21 这里需要从展示文字变更为展示物品icon
                    JPanel finalDetailPanel = detailPanel;
                    detailPanel.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            JPanel choosePanel = weaponMap.get(weapon);
                            chooseWeapon = weapon;
                            if (choosePanel == null) {
                                weaponMap.forEach((k, v) -> v.setBorder(new LineBorder(JBColor.YELLOW, 1)));
                                weaponMap.clear();
                            }
                            finalDetailPanel.setBorder(new LineBorder(JBColor.RED, 2));
                            weaponMap.put(weapon, finalDetailPanel);
                            playerWeaponTab.getDetailArea().setText(weapon.toString());
                        }
                    });
                    detailPanel.add(detailLabel, BorderLayout.CENTER);
                    detailRowPanel.add(detailPanel);
                }
                propsPanel.add(detailRowPanel);
            }

            log.info("当前的数据 {}", partition);
        });
    }

    /**
     * 加载世界Boss的游戏流程，和副本应该是一致的
     */
    private void loadBossTab() {
        tab.setSelectedIndex(4);
        JPanel boosPanel = masterGame.getBoosPanel();
        boosPanel.removeAll();
        boosPanel.setLayout(FLOW_LEFT_LAYOUT);
        boosPanel.setPreferredSize(maximumSize);
        playerWeaponTab = new EntryItemTab();
        JPanel detailPanel = playerWeaponTab.getDetailPanel();
        refreshPlayerWeapon();
        JTextArea detailArea = playerWeaponTab.getDetailArea();
        detailArea.setColumns(COLUMN_NUM);
        detailArea.setText("就是不给你看物品描述");
        boosPanel.add(detailPanel, new CellConstraints());
        updateUI(boosPanel);
    }

    /**
     * 加载副本Npc，玩家选择游戏副本之后加载此方法
     *
     * @param instance 查询条件
     */
    private void loadInstanceNpc(InstanceVo instance) {
        JPanel instancePanel = masterGame.getInstancePanel();
        instancePanel.removeAll();
        instancePanel.setLayout(FLOW_LEFT_LAYOUT);
        pvpTab = new PvpTab();

        playerArea = pvpTab.getPlayerArea();
        fightArea = pvpTab.getFightArea();
        JButton clearBtn = pvpTab.getClearBtn();
        clearBtn.addActionListener(e -> {
            fightArea.setText(Const.CLEAR_MSG);
            updateUI(tab, box, centerPanel);
        });
        JButton refreshBtn = pvpTab.getRefreshBtn();
        invoke(() -> refreshInstanceNpcList(instance));
        refreshBtn.addActionListener(e -> invoke(() -> refreshInstanceNpcList(instance)));
        instancePanel.add(pvpTab.getPvpPanel());
        updateUI(tab, instancePanel);
    }

    /**
     * 刷新npc列表
     * 玩家打败一个npc或者是败北后自动刷新
     *
     * @param instance 副本实例
     */
    private void refreshInstanceNpcList(InstanceVo instance) {
        Result result = HttpSendUtil.post(Const.INSTANCE_JOIN, new JoinInstanceDto(currentPlayer.getId(), instance.getId()));
        ChallengeInstanceVo challengeInstanceVo = ResultUtil.convertObjData(result, ChallengeInstanceVo.class);
        log.info("返回结果 {}", challengeInstanceVo);

        if (Const.ERROR_CODE.equals(result.getCode())) {
            fightArea.setText(result.toString());
            return;
        }

        // 防止出现战斗后列表紊乱的问题
        playerArea.removeAll();
        List<InstanceNpc> npcList = challengeInstanceVo.getNpcList();
        JPanel playerPanel = null;
        JButton battleBtn = null;
        JLabel playerInfoLabel = null;
        int size = npcList.size();
        playerArea.setLayout(new GridLayout(size, 1));
        pvpTab.getPlayerLabel().setText("NPC列表");
        Integer currentFloor = challengeInstanceVo.getRecord().getCurrentFloor();
        for (InstanceNpc instanceNpc : npcList) {
            playerPanel = new JPanel(FLOW_LEFT_LAYOUT);
            playerInfoLabel = new JLabel(String.format("[第%d层] [%s]", instanceNpc.getFloor(), instanceNpc.getNpcName()));
            boolean showBtnFlag = currentFloor.equals(instanceNpc.getFloor());
            Color labelColor = JBColor.GRAY;
            if (showBtnFlag) {
                labelColor = JBColor.GREEN;
            }
            if (instanceNpc.getBossFlag()) {
                labelColor = JBColor.RED;
            }
            playerInfoLabel.setForeground(labelColor);
            playerInfoLabel.setHorizontalAlignment(SwingConstants.LEFT);
            playerPanel.add(playerInfoLabel);

            if (showBtnFlag) {
                battleBtn = new JButton("战斗");
                playerPanel.add(battleBtn);
                battleBtn.addActionListener(e -> {
                    fightArea.setText(Const.CLEAR_MSG);
                    if (challengeInstanceVo.getRecord().getCompleteFlag()) {
                        fightArea.setText(Const.INSTANCE_OVER_MSG);
                        NotifyUtils.info(GAME_NAME, Const.INSTANCE_OVER_MSG, false);
                        JButton refreshBtn = pvpTab.getRefreshBtn();
                        refreshBtn.setText("返回列表");
                        refreshBtn.addActionListener(re -> invoke(this::loadInstanceTab));
                        updateUI(refreshBtn, tab, box, centerPanel);
                        return;
                    }
                    invoke(() -> {
                        Result processResult = HttpSendUtil.post(Const.NPC_CHALLENGE, new NpcFightDto(currentPlayer.getId(), instanceNpc));
                        BattleResult battleResult = ResultUtil.convertBattleResult(processResult, ProcessVo.class);
                        battleResult.getProcessList().forEach(this::addFightProcess);

                        playerArea.removeAll();
                        updateUI(playerArea);
                        refreshInstanceNpcList(instance);
                    });
                });
            }
            playerArea.add(playerPanel, BorderLayout.WEST);
        }
        updateUI(playerArea, tab, box, centerPanel);
    }

    /**
     * 更新UI， 传入若干个JComponent 按照顺序刷新
     *
     * @param panels 组件
     */
    private void updateUI(JComponent... panels) {
        Arrays.asList(panels).forEach(JComponent::updateUI);
    }

    /**
     * 刷新玩家列表
     */
    private void refreshPlayerList() {
        // 添加分页参数
        PlayerDto dto = new PlayerDto();
        if (page == null) {
            page = new Page<PlayerVo>();
            page.setCurrent(1);
            page.setSize(10);
        }
        if (searchTextField != null) {
            String nickname = searchTextField.getText();
            if (StrUtil.isNotBlank(nickname)) {
                dto.setNickname(nickname);
                page.setCurrent(1);
            }
        }
        dto.setPage(page);
        // 获取当前查询的玩家列表数据
        Result result = HttpSendUtil.post(Const.PLAYER_GET_ALL, dto);
        // 如果出现报错则战斗信息展示区域展示报错数据
        if (Const.ERROR_CODE.equals(result.getCode())) {
            fightArea.setText(result.toString());
            return;
        }
        // 防止出现战斗后列表紊乱的问题
        playerArea.removeAll();
        Page<PlayerVo> playerPage = ResultUtil.convertPageData(result.getData(), PlayerVo.class);
        page.setTotal(playerPage.getTotal());
        page.setCurrent(playerPage.getCurrent());
        page.setPages(playerPage.getPages());
        // 展示当前页数
        pageLabel.setText(playerPage.getCurrent() + "/" + playerPage.getPages());
        // 获取当前玩家
        List<PlayerVo> records = playerPage.getRecords();
        // 用来展示玩家信息的panel，
        JPanel playerPanel;
        // 挑战按钮
        JButton battleBtn;
        // 玩家信息
        JLabel playerInfoLabel;
        // 获取当前玩家信息，不可以挑战本人
        User currentUser = DataCache.getCurrentUser();
        int size = records.size();
        // 展示在线人数
        playerArea.setLayout(new GridLayout(size, 1));
        pvpTab.getPlayerLabel().setText(String.format("玩家列表(%s/%d)", result.getMessage(), playerPage.getTotal()));
        // 循环创建玩家数据 放到滚动面板当中
        for (PlayerVo record : records) {
            // 设置玩家信息左对齐
            playerPanel = new JPanel(FLOW_LEFT_LAYOUT);
            // 展示玩家省份，等级，昵称
            playerInfoLabel = new JLabel(String.format("%d [%s][Lv %d][%s]",
                    records.indexOf(record) + 1,
                    record.getRegion(),
                    record.getLevel(),
                    record.getNickname()
            ));
            // 在线玩家设置为绿色字体
            playerInfoLabel.setForeground(record.getOnline() ? JBColor.GREEN : JBColor.GRAY);
            playerInfoLabel.setHorizontalAlignment(SwingConstants.LEFT);
            playerPanel.add(playerInfoLabel);
            // 设置挑战按钮的点击事件
            if (!StrUtil.equalsIgnoreCase(record.getMac(), currentUser.getUuid())) {
                battleBtn = new JButton("挑战");
                playerPanel.add(battleBtn);
                battleBtn.addActionListener(e -> {
                    fightArea.setText(Const.CLEAR_MSG);
                    // 异步调用防止idea卡死
                    invoke(() -> {
                        Result processResult = HttpSendUtil.post(Const.BATTLE_DO, new BattleDto(record.getMac()));
                        BattleResult battleResult = ResultUtil.convertBattleResult(processResult, null);
                        List<ProcessVo> list = battleResult.getProcessList();
                        list.forEach(this::addFightProcess);
                        refreshPlayerList();
                        // 如果赢了可以选择是否发送鱼塘嘲讽
                        if (battleResult.getSuccess()) {
                            boolean confirmResult = AlertMessagesUtil.showYesNoDialog(GAME_NAME, StrUtil.format("恭喜你战胜了【{}】，是否发送鱼塘嘲讽", record.getNickname()));
                            if (confirmResult) {
                                log.info("你嘲讽了 {}", record.getNickname());
                                HttpSendUtil.post(Const.BATTLE_TAUNT, new TauntDto(currentUser.getUuid(), record.getMac()));
                            }
                        }
                    });
                });
            }
            playerArea.add(playerPanel, BorderLayout.WEST);
        }
        updateUI(playerArea, tab, box, centerPanel);
    }

    /**
     * 添加战斗过程输出到JTextArea中
     *
     * @param process 质感都过程
     */
    private void addFightProcess(ProcessVo process) {
        String processStr = process.getProcess();
        for (int i = 0; i < processStr.length(); i += COLUMN_NUM) {
            int end = Math.min(i + COLUMN_NUM, processStr.length());
            String chunk = processStr.substring(i, end);
            fightArea.append(String.format("\n%s", chunk));
        }
    }

    /**
     * 刷新centerPanel
     *
     * @param panel
     */
    private void refreshCenterPanel(JPanel panel) {
        centerPanel.removeAll();
        box.removeAll();
        box.add(panel);
        centerPanel.add(box);
        centerPanel.updateUI();
    }

    private void loginByMac() {
        User currentUser = DataCache.getCurrentUser();
        if (currentUser == null || StrUtil.isBlank(currentUser.getUuid())) {
            AlertMessagesUtil.showErrorDialog(GAME_NAME, "请先登录插件再进行游戏");
            new OverCommandHandler().handle(new String[]{"#over 9"});
            return;
        }
        invoke(() -> doLogin(LoginDto.macLogin()));
    }

    private void loginByAccount() {
        String accountStr = accountLogin.getAccount().getText();
        String pwdStr = accountLogin.getPassword().getText();
        if (StrUtil.isBlank(accountStr)) {
            NotifyUtils.error(GAME_NAME, "账号不允许为空");
            return;
        }

        if (StrUtil.isBlank(pwdStr)) {
            NotifyUtils.error(GAME_NAME, "密码不允许为空");
            return;
        }
        invoke(() -> doLogin(LoginDto.accountLogin(accountStr, pwdStr)));
    }

    /**
     * 执行登录操作，登录成功加载主游戏页面 PvpTab
     *
     * @param dto 登录dto
     */
    private void doLogin(LoginDto dto) {
        log.info("当前开始执行登录流程 地址 {}", Const.SYS_LOGIN);
        Result loginResult = HttpSendUtil.post(Const.SYS_LOGIN, dto);
        log.info("当前登录返回结果 -{}", loginResult);
        if (loginResult.getCode() == 200) {
            PlayerInfoVo playerInfoVo = ResultUtil.convertObjData(loginResult, PlayerInfoVo.class);
            currentPlayer = playerInfoVo;
            DataCache.loginToken = String.format("Bearer %s", playerInfoVo.getToken());
            initMasterGame();
        } else {
            AlertMessagesUtil.showErrorDialog(GAME_NAME, loginResult.getMessage());
        }
    }

}
